package com.gulimall.search.web;

import java.util.concurrent.*;

/**
 * @author coder_ccy
 * @date 2022/3/30 16:12
 */
public class Demo03 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {


        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(10000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );


        // 没有返回值的异步任务
//        CompletableFuture.runAsync(()->{
//            System.out.println("执行异步任务");
//        },poolExecutor);

//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("执行异步任务，有返回值");
//            return 10;
//        }, poolExecutor);
//
//        System.out.println("这是我的主线程");
//        System.out.println(future.get());



        //whenCompleteAsync  判断执行是否成功，不能改变返回值
//        CompletableFuture<Integer> fu = CompletableFuture.supplyAsync(() -> {
//            System.out.println("执行异步任务，有返回值");
//            int i = 1 / 0;
//            return 10;
//        }, poolExecutor).whenCompleteAsync((integer, exp) -> {
//            //如果执行没有异常，integer获取值   exp为null
//
//            //如果执行有异常，integer就为null, exp有值
//
//            if (integer != null) { //执行成功
//
//
//            }
//            if (exp != null) { //执行失败
//                integer = 0;
//            }
//
//
//            System.out.println("integer:" + integer);
//            System.out.println("exp:" + exp);
//
//        });
//
//        System.out.println(fu.get());


        // exceptionally   出现异常，可以改变返回结果
//        CompletableFuture<Integer> fu = CompletableFuture.supplyAsync(() -> {
//            System.out.println("执行异步任务，有返回值");
//            int i = 1 / 0;
//            System.out.println("正常执行业务");
//            return 10;
//        }, poolExecutor).exceptionally((exp)->{
//            System.out.println("出现异常，给默认值");
//            return 0;
//        });
//
//        System.out.println(fu.get());



        // handleAsync 可以改变返回结果
//        CompletableFuture<Integer> fu = CompletableFuture.supplyAsync(() -> {
//            System.out.println("执行异步任务，有返回值");
////            int i = 1 / 0;
//            System.out.println("正常执行业务");
//            return 16;
//        }, poolExecutor).handleAsync((result,exp)->{
//            if(result<15)
//            return 11+result;
//            else return result;
//            }, poolExecutor);
//
//        System.out.println(fu.get());

        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("执行第一个异步任务");

            return 10;
        },poolExecutor);

        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("执行第二个异步任务");

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return 20;
        },poolExecutor);

        CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {
            System.out.println("执行第三个异步任务");
        }, poolExecutor);

        //thenRunAsync  执行完第一个任务，执行第二个，没有数据传递
//        future1.thenRunAsync(()->{
//            System.out.println("执行第二个异步任务，不需要接受第一个异步任务的返回结果");
//        },poolExecutor);


        // thenAcceptAsync  执行完第一个任务,将结果给第二个任务【第二个任务没有返回值】
//        future1.thenAcceptAsync((ret)->{
//            System.out.println("获得第一个异步任务的结果："+ret);
//        },poolExecutor);

        //  thenApplyAsync 执行完第一个任务,将结果给第二个任务【第二个任务有返回值】
//        CompletableFuture<Integer> f = future1.thenApplyAsync((ret) -> {
//            System.out.println("第二个异步任务执行，获得第一个异步任务的结果："+ret);
//            return ret + 100;
//        });
//        System.out.println(f.get());


        //runAfterBoth
//        future1.runAfterBothAsync(future2,()->{
//            System.out.println("我是第三个异步任务，需要等他俩运行完，我才能运行");
//        },poolExecutor);


        //thenAcceptBoth
//        future1.thenAcceptBothAsync(future2,(ret1,ret2)->{
//            System.out.println("我是第三个异步任务，需要等他俩运行完，我才能运行,获得他俩返回值，ret1:"+ret1+",ret2="+ret2);
//
//        },poolExecutor);

        //thenCombine

//        CompletableFuture<Integer> future = future1.thenCombineAsync(future2, (ret1, ret2) -> {
//            System.out.println("我是第三个异步任务，需要等他俩运行完，我才能运行,获得他俩返回值，ret1:" + ret1 + ",ret2=" + ret2);
//            return ret1 + ret2;
//        }, poolExecutor);
//
//        System.out.println(future.get());


        //runAfterEither
//        future1.runAfterEitherAsync(future2,()->{
//            System.out.println("我是第三个异步任务，需要等他俩之一运行完，我就能运行");
//        },poolExecutor);


        //acceptEither
//        future1.acceptEitherAsync(future2,(ret)->{
//            System.out.println("我是第三个异步任务，需要等他俩一个运行完,获得返回值，ret:"+ret);
//
//        },poolExecutor);

        //applyToEither

//        CompletableFuture<Integer> future = future1.applyToEitherAsync(future2, (ret) -> {
//            System.out.println("我是第三个异步任务，需要等他俩之一运行完，我才能运行,获得他俩返回值，ret:" + ret);
//            return ret+100;
//        }, poolExecutor);
//
//        System.out.println(future.get());

//        CompletableFuture<Void> future = CompletableFuture.allOf(future1, future2, future3);

        //阻塞
//        CompletableFuture<Object> future4 = future.thenApplyAsync(new Function<Void, Object>() {
//            @Override
//            public Object apply(Void unused) {
//
//                System.out.println("主任务执行");
//                try {
//                    System.out.println(future1.get());
//                    System.out.println(future2.get());
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                } catch (ExecutionException e) {
//                    e.printStackTrace();
//                }
//
//                return 33;
//            }
//        });

//        future.get();
//        System.out.println("阻塞结束，主任务执行");
//        System.out.println(future1.get());
//        System.out.println(future2.get());


        // anyOf  其中一个执行完就可以

        CompletableFuture<Object> fu = CompletableFuture.anyOf(future1, future2, future3);


        Object result = fu.get();

        System.out.println("阻塞结束，获得结果："+result);



    }
}
